package Kuaishou;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

/**
 * Java在JDK7之后加入了并行计算的框架Fork/Join，可以解决我们系统中大数据计算的性能问题。
 * Fork/Join采用的是分治法，Fork是将一个大任务拆分成若干个子任务，子任务分别去计算，而Join是获取到子任务的计算结果，然后合并，这个是递归的过程。
 * 子任务被分配到不同的核上执行时，效率最高。
 */
public class Test17并行计算3 extends RecursiveAction {

    /**
     *  每个"小任务"最多只打印20个数
     */
    private static final int MAX = 20;

    private int start;
    private int end;

    public Test17并行计算3(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected void compute() {
        //当end-start的值小于MAX时，开始打印
        if((end-start) < MAX) {
            for(int i= start; i<end;i++) {
                System.out.println(Thread.currentThread().getName()+" i的值"+i);
            }
        }else {
            // 将大任务分解成两个小任务
            int middle = (start + end) / 2;
            Test17并行计算3 left = new Test17并行计算3(start, middle);
            Test17并行计算3 right = new Test17并行计算3(middle, end);
            left.fork();
            right.fork();
            left.join();
            right.join();
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建包含Runtime.getRuntime().availableProcessors()返回值作为个数的并行线程的ForkJoinPool
        ForkJoinPool forkJoinPool = new ForkJoinPool();

        long start = System.currentTimeMillis();
        // 提交可分解的PrintTask任务
        forkJoinPool.submit(new Test17并行计算3(0, 50000)).join();

        System.out.println("join,耗时：" + (System.currentTimeMillis() - start) + "ms");
    }
}
